package com.global.college.api;


import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.global.college.UserData;
import com.global.college.ui.bean.InviteHistoryModel;
import com.global.college.ui.bean.InviteInfoModel;
import com.global.college.ui.bean.LoginModel;
import com.global.college.ui.bean.UploadHeaderModel;
import com.global.college.ui.bean.UserDataModel;
import com.global.college.ui.bean.WechatLoginModel;
import com.global.college.utils.StringUtils;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import rx.Observable;
import rx.android.BuildConfig;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

/**
 * Created by fu on 2020/2/16.
 * Describe: 客户端请求
 */
@SuppressWarnings("unchecked")
public class AuthRequestClient {

    private final static String TAG = "RequestClient";

    /**
     * 超时时间(秒)
     */
    public static final int DEFAULT_TIMEOUT = 1800;

    public static Observable.Transformer IO_UI = new ClassicIOTransformer();
    /**
     * 单例
     */
    private static AuthRequestClient authRequestClient;

    private static HttpLoggingInterceptor BODY_LOGGER = new HttpLoggingInterceptor();
    private static HttpLoggingInterceptor BASIC_LOGGER = new HttpLoggingInterceptor();

    private Retrofit mRetrofit;

    private AuthServerAPI mAuthServerApi;
    private String app = "app";


    public void setDebug() {
        if (BuildConfig.DEBUG) {
            BODY_LOGGER.setLevel(HttpLoggingInterceptor.Level.BODY);
            BASIC_LOGGER.setLevel(HttpLoggingInterceptor.Level.BASIC);
        } else {
            BODY_LOGGER.setLevel(HttpLoggingInterceptor.Level.NONE);
            BASIC_LOGGER.setLevel(HttpLoggingInterceptor.Level.NONE);
        }
    }

    private AuthRequestClient() {
        //系统平台版本号
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);//超时时间
        builder.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);//上传超时时间
        builder.retryOnConnectionFailure(true);//启用自动重连
        //拦截器－添加公共字段
        //builder.addInterceptor(commonInterceptor);
        //builder.addNetworkInterceptor(new LoggingInterceptor());
        builder.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY));//这是打印所有日志
        builder.addInterceptor(new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request newRequest = chain.request().newBuilder().header("client-type", "app").build();
                return chain.proceed(newRequest);
            }
        });

        setDebug();
        OkHttpClient okHttpClient = builder.build();
        mRetrofit = new Retrofit.Builder()
                .baseUrl(AuthURLs.BASE_URL)
                .client(okHttpClient)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
        mAuthServerApi = mRetrofit.create(AuthServerAPI.class);
    }

    //外部调用
    @SuppressWarnings("unchecked")
    public static AuthRequestClient getInstance() {
        if (null == authRequestClient) {
            authRequestClient = new AuthRequestClient();
        }
        return authRequestClient;
    }


    /**
     * 2. 获取微信access_token
     */
    public Observable<BaseResponseModel> getWechatToken(String appId, String secret, String code, String grant_type) {

        return mAuthServerApi.getWechatToken(appId, secret, code, grant_type)
                .map(new HttpResultFunc<>())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());

    }

    /**
     * 3.用户注册
     * phone         手机号
     * code          验证码
     * password      密码
     * source      来源
     */
    public Observable<BaseResponseModel> regist(String phone, String code, String password,String inviteCode) {
        JsonObject jObj = new JsonObject();
        jObj.addProperty("username", phone);
        jObj.addProperty("code", code);
        jObj.addProperty("password", password);
        jObj.addProperty("source", "uton_edu_android");
        jObj.addProperty("clientId", "edu_client");
        jObj.addProperty("invitationCode", inviteCode);
        String body = new Gson().toJson(jObj);
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), body);
        return mAuthServerApi.regist(requestBody)
                .map(new HttpResultFunc<>())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 获取邀请信息
     * @return
     */
    public Observable<InviteInfoModel> getInviteInfo() {
        return mAuthServerApi.getInviteInfo(UserData.getInstance().getToken())
                .map(new HttpResultFunc<>())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<InviteHistoryModel> getInviteRegisterRecord(int pageNum,int pageSize) {
        return mAuthServerApi.getInviteRegisterList(UserData.getInstance().getToken(),pageNum,pageSize)
                .map(new HttpResultFunc<>())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<InviteHistoryModel> getInvitePaidList(int pageNum,int pageSize) {
        return mAuthServerApi.getInvitePaidList(UserData.getInstance().getToken(),pageNum,pageSize)
                .map(new HttpResultFunc<>())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 4.登录
     * username	     用户名
     * password	    密码
     * code	        验证码
     * source	    来源
     */
    public Observable<LoginModel> login(String phone, String password, String code) {
        JsonObject jObj = new JsonObject();
        jObj.addProperty("username", phone);
        if (StringUtils.isNotEmpty(code, true)) {
            jObj.addProperty("code", code);
        }
        if (StringUtils.isNotEmpty(password, true)) {
            jObj.addProperty("password", password);
        }
        jObj.addProperty("source", "uton_edu_android");
        String body = new Gson().toJson(jObj);
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), body);
        return mAuthServerApi.login(requestBody)
                .map(new HttpResultFunc<>())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 5.找回密码
     * code	        验证码
     * password	    密码
     * username	    用户名
     */

    public Observable<BaseResponseModel> findPsw(String phone, String code, String password) {
        JsonObject jObj = new JsonObject();
        jObj.addProperty("username", phone);
        jObj.addProperty("code", code);
        jObj.addProperty("password", password);
        String body = new Gson().toJson(jObj);
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), body);
        return mAuthServerApi.findPsw(requestBody)
                .map(new HttpResultFunc<>())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 6.退出登录
     */

    public Observable<BaseResponseModel> loginOut() {
        return mAuthServerApi.loginOut(UserData.getInstance().getToken())
                .map(new HttpResultFunc<>())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 7.获取验证码
     * phone	手机号
     */
    public Observable<BaseResponseModel> getSmsCode(String phone) {
        JsonObject jObj = new JsonObject();
        jObj.addProperty("phone", phone);
        String body = new Gson().toJson(jObj);
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), body);
        return mAuthServerApi.getSmsCode(requestBody)
                .map(new HttpResultFunc<>())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 10. 修改用户手机号
     * Authorization
     * code	        验证码
     * phone        电话
     * userName	    用户账号
     */

    public Observable<BaseResponseModel> editPhone(String phone, String code, String userName) {
        JsonObject jObj = new JsonObject();
        jObj.addProperty("phone", phone);
        jObj.addProperty("code", code);
        jObj.addProperty("userName", userName);
        String body = new Gson().toJson(jObj);
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), body);
        return mAuthServerApi.editPhone(UserData.getInstance().getToken(), requestBody)
                .map(new HttpResultFunc<>())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 11.修改用户密码
     * Authorization
     * confirmPassword	    确认密码
     * newPassword	        新密码
     * oldPassword	        原密码
     * userName	            用户账号
     */
    public Observable<BaseResponseModel> editPsw(String confirmPassword, String newPassword, String oldPassword, String userName) {
        JsonObject jObj = new JsonObject();
        jObj.addProperty("confirmPassword", confirmPassword);
        jObj.addProperty("newPassword", newPassword);
        jObj.addProperty("oldPassword", oldPassword);
        jObj.addProperty("userName", userName);
        String body = new Gson().toJson(jObj);
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), body);
        return mAuthServerApi.editPsw(UserData.getInstance().getToken(), requestBody)
                .map(new HttpResultFunc<>())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 12.获取用户信息
     * Authorization
     */
    public Observable<UserDataModel> getUserInfo() {
        return mAuthServerApi.getUserInfo(UserData.getInstance().getToken())
                .map(new HttpResultFunc<>())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 12.设置用户信息
     * Authorization
     * avatar	     用户头像
     * nickName	     用户昵称
     * sex	        用户性别 用户性别（0男 1女 2未知）
     * userName	    用户账号
     */


    public Observable<BaseResponseModel> setUserInfo(String avatar, String nickName, String sex, String userName) {
        JsonObject jObj = new JsonObject();
        if (StringUtils.isNotEmpty(avatar, true)) {
            jObj.addProperty("avatar", avatar);
        }
        if (StringUtils.isNotEmpty(nickName, true)) {
            jObj.addProperty("nickName", nickName);
        }
        if (StringUtils.isNotEmpty(sex, true)) {
            jObj.addProperty("sex", sex);
        }
        jObj.addProperty("userName", userName);
        String body = new Gson().toJson(jObj);
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), body);
        return mAuthServerApi.setUserInfo(UserData.getInstance().getToken(), requestBody)
                .map(new HttpResultFunc<>())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 14. 上传头像
     * Authorization
     * fileName	文件类型
     */
    public Observable<UploadHeaderModel> uploadAvatar(String fileName) {
        File file = new File(fileName);
        RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM)
                .addFormDataPart("fileName", file.getName(), MultipartBody.create(MediaType.parse("image/*"), file))
                .build();
        return mAuthServerApi.uploadAvatar(UserData.getInstance().getToken(), requestBody)
                .map(new HttpResultFunc<>())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }
}